package minio.web.controller;

import cn.hutool.core.date.DateUtil;
import minio.web.domain.FileDetail;
import minio.web.mapper.FileDetailMapper;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.dromara.x.file.storage.core.constant.Constant;
import org.dromara.x.file.storage.core.presigned.GeneratePresignedUrlResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @author ljl
 * @date 2024/9/19 下午2:29
 * @description FileDetailController
 */
@RestController
public class FileDetailController {

    @Autowired
    private FileDetailMapper fileDetailMapper;
    @Autowired
    private FileStorageService fileStorageService;//注入实列

    /**
     * 上传文件
     */
    @PostMapping("/upload")
    public FileInfo upload(MultipartFile file) {
        FileInfo upload = fileStorageService.of(file).upload();
        return upload;
    }

    @GetMapping("/getFile")
    public FileInfo getFile() {
        FileInfo fileInfo = fileStorageService.getFileInfoByUrl("http://127.0.0.1:9000/test/66ebe3b4304c700a68a9735d.png");
        return fileInfo;
    }

    @GetMapping("/download")
    public String download(@RequestParam String url) {
        // 获取一个 FileInfo
        FileInfo fileInfo = fileStorageService.getFileInfoByUrl(url);

        // 生成下载或访问用的 URL
        GeneratePresignedUrlResult downloadResult = fileStorageService
                .generatePresignedUrl()
                .setPlatform(fileInfo.getPlatform()) // 存储平台，不传使用默认的
                .setPath(fileInfo.getPath()) // 文件路径
                .setFilename(fileInfo.getFilename()) // 文件名，也可以换成缩略图的文件名
                .setMethod(Constant.GeneratePresignedUrl.Method.GET) // 签名方法
                .setExpiration(DateUtil.offsetMinute(new Date(), 10)) // 过期时间 10 分钟
                .putResponseHeaders(
                        // 设置一个响应头，将下载时的文件名改成 NewDownloadFileName.jpg，不需要可省略
                        // 这里也可以设置其它的想要的响应头，每个存储平台支持情况都不太相同，可以自行测试或查询相关文档
                        Constant.Metadata.CONTENT_DISPOSITION, "attachment;filename="+fileInfo.getOriginalFilename())
                .generatePresignedUrl();
        return downloadResult.getUrl();
    }


    @GetMapping("/download2")
    public byte[] download2(@RequestParam String url) {
        FileInfo fileInfo = fileStorageService.getFileInfoByUrl(url);
        return fileStorageService.download(fileInfo).bytes();
    }

    @GetMapping("/img/{imdId}")
    public byte[] img(@PathVariable String imdId) {
        FileDetail fileDetail = fileDetailMapper.selectById(imdId);
        FileInfo fileInfo = fileStorageService.getFileInfoByUrl(fileDetail.getUrl());
        return fileStorageService.download(fileInfo).bytes();
    }

    @GetMapping("/minImg/{imdId}")
    public byte[] minImg(@PathVariable String imdId) {
        FileDetail fileDetail = fileDetailMapper.selectById(imdId);
        FileInfo fileInfo = fileStorageService.getFileInfoByUrl(fileDetail.getThUrl());
        return fileStorageService.download(fileInfo).bytes();
    }

    /**
     * 上传文件，成功返回文件 url
     */
    @PostMapping("/upload2")
    public String upload2(MultipartFile file) {
        FileInfo fileInfo = fileStorageService.of(file)
                .setPath("upload/") //保存到相对路径下，为了方便管理，不需要可以不写
                .setSaveFilename("image.jpg") //设置保存的文件名，不需要可以不写，会随机生成
                .setObjectId("0")   //关联对象id，为了方便管理，不需要可以不写
                .setObjectType("0") //关联对象类型，为了方便管理，不需要可以不写
                .putAttr("role","admin") //保存一些属性，可以在切面、保存上传记录、自定义存储平台等地方获取使用，不需要可以不写
                .upload();  //将文件上传到对应地方
        return fileInfo == null ? "上传失败！" : fileInfo.getUrl();
    }

    /**
     * 上传图片，成功返回文件信息
     * 图片处理使用的是 https://github.com/coobird/thumbnailator
     */
    @PostMapping("/upload-image")
    public FileInfo uploadImage(MultipartFile file) {
        return fileStorageService.of(file)
                .image(img -> img.size(1000,1000))  //将图片大小调整到 1000*1000
                .thumbnail(th -> th.size(200,200))  //再生成一张 200*200 的缩略图
                .upload();
    }

    /**
     * 上传文件到指定存储平台，成功返回文件信息
     */
    @PostMapping("/upload-platform")
    public FileInfo uploadPlatform(MultipartFile file) {
        return fileStorageService.of(file)
                .setPlatform("aliyun-oss-1")    //使用指定的存储平台
                .upload();
    }

    /**
     * 直接读取 HttpServletRequest 中的文件进行上传，成功返回文件信息
     * 使用这种方式有些注意事项，请查看文档 基础功能-上传 章节
     */
    @PostMapping("/upload-request")
    public FileInfo uploadPlatform(HttpServletRequest request) {
        return fileStorageService.of(request).upload();
    }
}
